package org.fund.base_service.service.impl;

import com.github.pagehelper.PageHelper;
import org.fund.base_service.domain.IncomeRecord;
import org.fund.base_service.domain.input.base.PageDomain;
import org.fund.base_service.domain.vo.PositionBO;
import org.fund.base_service.mapper.IncomeRecordMapper;
import org.fund.base_service.mapper.PositionMapper;
import org.fund.base_service.service.IncomeRecordService;
import org.fund.common.model.FundValueEntity;
import org.fund.common.util.BigDecimalUtils;
import org.fund.common.util.DateUtils;
import org.fund.common.util.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 收益记录(IncomeRecord)表服务实现类
 *
 * @author makejava
 * @since 2022-03-13 01:24:54
 */
@Service
public class IncomeRecordServiceImpl implements IncomeRecordService {
    @Autowired
    private IncomeRecordMapper incomeRecordMapper;

    @Autowired
    private  TempFundService tempFundService;

    @Autowired
    private PositionMapper positionMapper;
    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public IncomeRecord queryById(Integer id) {
        return this.incomeRecordMapper.queryById(id);
    }

    /**
     * 分页查询
     *
     * @param pageDomain 筛选条件
     * @return 查询结果
     */
    @Override
    public PageInfo<IncomeRecord> queryByPage(PageDomain pageDomain) {
        PageHelper.startPage(pageDomain.getPageNum(), pageDomain.getPageSize());
        List<IncomeRecord> list = incomeRecordMapper.queryAll(SecurityUtils.getUserId());
        List<IncomeRecord> reverse = list.stream().sorted(Comparator.comparing(IncomeRecord::getIncomeDate).reversed()).collect(Collectors.toList());
        PageInfo page = new PageInfo(reverse);
        return page;
    }

    /**
     * 新增数据
     *
     * @param incomeRecord 实例对象
     * @return 实例对象
     */
    @Override
    public IncomeRecord insert(IncomeRecord incomeRecord) {
        this.incomeRecordMapper.insert(incomeRecord);
        return incomeRecord;
    }

    /**
     * 修改数据
     *
     * @param incomeRecord 实例对象
     * @return 实例对象
     */
    @Override
    public IncomeRecord update(IncomeRecord incomeRecord) {
        this.incomeRecordMapper.update(incomeRecord);
        return this.queryById(incomeRecord.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.incomeRecordMapper.deleteById(id) > 0;
    }

    /**
     * 计算当日收益
     * @return
     */
    @Override
    public List<IncomeRecord> calculateIncome() {
        // 如果是节假日或者周末就不计算收益
        if (DateUtils.isHolidayAndWeekend(DateUtils.getCurrentDay())==0){
            return Collections.emptyList();
        }
        // 查出所有的持仓数据
        List<PositionBO> allWithUserId = positionMapper.getAllWithUserId();
        Map<String, List<PositionBO>> groupByFundCode = getJZMapByFundCode(allWithUserId);
        //根据当前日期获取净值数据
        Map<String, FundValueEntity> currentJZ = tempFundService.queryByFundCodeAndDate(DateUtils.getCurrentDay());
//        Map<String, FundValueEntity> currentJZ = tempFundService.queryByFundCodeAndDate("2022-03-24");
        // 获取前一天净值数据
//        Map<String, FundValueEntity> beforeJZ = tempFundService.queryByFundCodeAndDate("2022-03-23");
        Map<String, FundValueEntity> beforeJZ = getBeforeJZ(DateUtils.getCurrentDay());
        List<IncomeRecord> incomeRecordList = getIncomeRecords(allWithUserId, groupByFundCode, currentJZ, beforeJZ);
        return incomeRecordList;
    }

    /**
     *
     * @param allWithUserId
     * @return
     */
    private Map<String, List<PositionBO>> getJZMapByFundCode(List<PositionBO> allWithUserId) {
        Map<String,List<PositionBO>> groupByFundCode = new HashMap<>();
        for (int i = 0; i < allWithUserId.size(); i++) {
            List<PositionBO> temp = new ArrayList<>();
            String fundCode = allWithUserId.get(i).getFundCode();

            if(groupByFundCode.containsKey(fundCode)) {
                continue;
            }
            temp.add(allWithUserId.get(i));
            //最后一个元素 不存在直接添加到map中
            if (i==allWithUserId.size()-1){
                groupByFundCode.put(fundCode, temp);
                break;
            }
            for (int j = i+1; j < allWithUserId.size(); j++) {
                if (allWithUserId.get(j).getFundCode().equals(fundCode)){
                    temp.add(allWithUserId.get(j));
                }
            }
            groupByFundCode.put(fundCode, temp);
        }
        return groupByFundCode;
    }

    private Map<String, FundValueEntity> getBeforeJZ(String currentDay) {
        String dayBefore;
        Map<String, FundValueEntity> beforeJZ = new HashMap<>();
        if (DateUtils.isMonday(currentDay)){
//        if (DateUtils.isMonday("2022-03-21")){
            try {
                dayBefore = DateUtils.getDay(currentDay,1);
                beforeJZ = tempFundService.queryByFundCodeAndDate(dayBefore);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else{
            beforeJZ = tempFundService.queryByFundCodeAndDate(DateUtils.getDayBefore());
        }
        return beforeJZ;
    }

    /**
     * 计算收益记录
     * @param allWithUserId
     * @param groupByFundCode
     * @param currentJZ
     * @param beforeJZ
     * @return
     */
    private List<IncomeRecord> getIncomeRecords(List<PositionBO> allWithUserId, Map<String, List<PositionBO>> groupByFundCode, Map<String, FundValueEntity> currentJZ, Map<String, FundValueEntity> beforeJZ) {
        List<IncomeRecord> incomeRecordList = new ArrayList<>(allWithUserId.size());
        for (String s : groupByFundCode.keySet()) {
            FundValueEntity before = beforeJZ.get(s);
            FundValueEntity current = currentJZ.get(s);
            List<PositionBO> list = groupByFundCode.get(s);
            for (PositionBO p : list) {
                //计算收益
                IncomeRecord re = new IncomeRecord();
                BigDecimal income = p.getHoldAmount().multiply(BigDecimalUtils.subtract(current.getDWJZ(), before.getDWJZ())).setScale(2, BigDecimal.ROUND_HALF_UP);
                BeanUtils.copyProperties(p,re);
                re.setIncome(income);
                re.setIncomeDate(current.getFSRQ());
                re.setIncreasePercent(new BigDecimal(current.getJZZZL()));
                re.setUId(p.getUId());
                re.setDwjz(current.getDWJZ());
                incomeRecordList.add(re);
            }
        }
        return incomeRecordList;
    }

    @Override
    public int batchInsert(List<IncomeRecord> incomeRecordList) {
        // 如果是节假日或者周末就不计算收益
        if (DateUtils.isHolidayAndWeekend(DateUtils.getCurrentDay())==0){
            return  0;
        }
        return incomeRecordMapper.insertBatch(incomeRecordList);
    }
}
